package com.freight.tws.third;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freight.common.core.constant.OpenConstants;
import com.freight.common.core.exception.ServiceException;
import com.freight.common.core.utils.DateUtils;
import com.freight.common.core.utils.StringUtils;
import com.freight.common.redis.service.RedisService;
import com.freight.tws.api.RemoteConfigClient;
import com.freight.tws.api.domain.Vehicle;
import com.freight.tws.domain.vo.LocationVO;
import com.freight.tws.service.IVehicleService;
import com.openapi.sdk.service.DataExchangeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 中交兴路
 */
@Component
public class OpenApiService {

    @Autowired
    private RemoteConfigClient remoteConfigClient;

    @Autowired
    RedisService redisService;

    @Autowired
    private IVehicleService vehicleService;

    private String URL = "";
    private String USER = "";
    private String PWD = "";
    private String SRT = "";
    private String CLIENTID = "";

    public void init() {
        this.URL = remoteConfigClient.selectConfigByKey("open.api.url");
        this.USER = remoteConfigClient.selectConfigByKey("open.api.user");
        this.PWD = remoteConfigClient.selectConfigByKey("open.api.pwd");
        this.SRT = remoteConfigClient.selectConfigByKey("open.api.srt");
        this.CLIENTID = remoteConfigClient.selectConfigByKey("open.api.clientId");
    }

    /**
     * 获取令牌
     */
    public String getOpenToken() {
        this.init();
        String token = redisService.getCacheObject(OpenConstants.OPEN_TOKEN_);
        if(StringUtils.isBlank(token)) {
            try {
                Map<String, String> map = new HashMap<String, String>(4);
                map.put("user", USER);
                map.put("pwd", PWD);
                map.put("srt", SRT);
                map.put("cid", CLIENTID);
                String result = send(URL + "/save/apis/login", map);
                if (StringUtils.isNotBlank(result)) {
                    token = result;
                    redisService.setCacheObject(OpenConstants.OPEN_TOKEN_, result, (long) 2626560, TimeUnit.SECONDS);
                }
            } catch (Exception e) {
                System.out.println("e:" + e.getMessage());
            }
        }
        return token;
    }

    /**
     * 一、 多车辆最新位置查询（车牌号）接口
     * 本接口提供指定车牌号的车辆最新位置查询。
     */
    public List<LocationVO> vLastLocationV4(String plateNumbers) {
        List<LocationVO> list = new ArrayList<>();
        String token = getOpenToken();
        try {
            Map<String, String> map = new HashMap<String, String>(3);
            map.put("token", token);
            map.put("cid", CLIENTID);
            map.put("srt", SRT);
            map.put("vclNs",plateNumbers);
            map.put("timeNearby", "30");
            String result = send(URL + "/save/apis/vLastLocationMultiV4", map);
            if(StringUtils.isNotBlank(result)) {
                list = JSONObject.parseArray(result, LocationVO.class);
            }
        } catch (Exception e) {
            System.out.println("e:" + e.getMessage());
        }
        return list;
    }

    /**
     * 获取单车实时位置
     * @param plateNumber
     * @return
     */
    public LocationVO vLastLocationV3(String plateNumber) {
        LocationVO  lovation = null;
        String token = getOpenToken();
        try {
            Map<String, String> map = new HashMap<String, String>(3);
            map.put("token", token);
            map.put("cid", CLIENTID);
            map.put("srt", SRT);
            map.put("vclN", plateNumber);
            map.put("timeNearby", "30");
            String result = send(URL + "/save/apis/vLastLocationV3", map);
            if(StringUtils.isNotBlank(result)) {
                lovation = JSON.parseObject(result, LocationVO.class);
            }
        } catch (Exception e) {
            System.out.println("e:" + e.getMessage());
        }
        return lovation;
    }

    /**
     * 获取车辆轨迹（时间段-单日）
     * @param plateNumber
     * @param dBegin
     * @param dEnd
     * @return
     */
    public JSONArray vHisTrack24(String plateNumber, Date dBegin, Date dEnd) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String begin = formatter.format(dBegin);
        String end = formatter.format(dEnd);
        JSONArray array = null;
        String token = getOpenToken();

        try {
            Map<String, String> map = new HashMap<String, String>(3);
            map.put("token", token);
            map.put("cid", CLIENTID);
            map.put("srt", SRT);
            map.put("vclN",plateNumber);
            map.put("qryBtm",begin);
            map.put("qryEtm",end);
            String result = send(URL + "/save/apis/vHisTrack24", map);
            if(StringUtils.isNotBlank(result)) {
                array = JSON.parseArray(result);
            }
        } catch (Exception e) {
            System.out.println("e:" + e.getMessage());
        }
        return array;
    }

    /**
     * 获取某一整天的轨迹
     * @param plateNumber
     * @param day
     * @return
     */
    public JSONArray vHisTrack24(String plateNumber, String day) {
        JSONArray array = null;
        String token = getOpenToken();
        try {
            Map<String, String> map = new HashMap<String, String>(3);
            map.put("token", token);
            map.put("cid", CLIENTID);
            map.put("srt", SRT);
            map.put("vclN",plateNumber);
            map.put("qryBtm",day);
            map.put("qryEtm",day);
            String result = send(URL + "/save/apis/vHisTrack24", map);
            if(StringUtils.isNotBlank(result)) {
                array = JSON.parseArray(result);
            }
        } catch (Exception e) {
            System.out.println("e:" + e.getMessage());
        }
        return array;
    }

    /**
     * 获取某一时间段内的轨迹（跨天）
     * @param plateNumber
     * @param dBegin
     * @param dEnd
     * @return
     */
    public String vHisTrack(String plateNumber, Date dBegin, Date dEnd) {
        JSONArray jsonArray =  new JSONArray();
        List<Date> between = DateUtils.getAllDatesBetweenTwoDates(dBegin,dEnd);
        if(between.size() == 0) {
            jsonArray = vHisTrack24(plateNumber,dBegin,dEnd);
        } else {
            for(int i = 0; i < between.size(); i++) {
                if(i == 0) {
                    //获取第一天的结束时
                    jsonArray = vHisTrack24(plateNumber,dBegin,between.get(i));
                } else {
                    JSONArray listMiddel = vHisTrack24(plateNumber, between.get(i-1), between.get(i));
                    jsonArray.addAll(listMiddel);
                }
            }
            JSONArray listEnd = vHisTrack24(plateNumber, between.get(between.size()-1), dEnd);
            jsonArray.addAll(listEnd);
        }
        System.out.println("***********"+jsonArray);
        return StringUtils.join(jsonArray, ",");
    }

    /**
     * 离线车辆注册
     * @param ids
     * @return
     */
    public boolean vnoOutReg(List<Long> ids) {
        if(ids.size() > 0) {
            try {
                List<Vehicle> cars = vehicleService.listByIds(ids);
                StringBuffer sb = new StringBuffer();
                for (Vehicle car : cars) {
//                    if(DictConstants.IS_WARNING.NO.getKey().equals(car.getIsWarning())) {
//                        sb.append(car.getVehicleNumber());
//                        sb.append("_");
//                        sb.append(car.getPlateColor());
//                        sb.append(",");
//                    }
//                    car.setIsWarning(DictConstants.IS_WARNING.YES.getKey());
                }
                if(StringUtils.isNotBlank(sb)) {
                    String token = getOpenToken();
                    Map<String, String> map = new HashMap<String, String>(3);
                    map.put("token", token);
                    map.put("cid", CLIENTID);
                    map.put("srt", SRT);
                    map.put("userflag", "sth");
                    map.put("vnos", sb.toString());
                    String result = send(URL + "/save/apis/vnoOutReg", map);
                    if(StringUtils.isNotBlank(result) && "1".equals(result)) {
                        // 更新订阅状态
                        vehicleService.updateBatchById(cars);
                        return true;
                    }
                }
            } catch (Exception e) {
                System.out.println("e:" + e.getMessage());
            }
        }
        return false;
    }

    /** 删除离线车辆订阅接口 */
    public boolean vnoOutDel(List<Long> ids) {
        if(ids.size() > 0) {
            try {
                List<Vehicle> cars = vehicleService.listByIds(ids);
                StringBuffer sb = new StringBuffer();
                for (Vehicle car : cars) {
//                    if(DictConstants.IS_WARNING.YES.getKey().equals(car.getIsWarning())) {
//                        sb.append(car.getVehicleNumber());
//                        sb.append("_");
//                        sb.append(car.getPlateColor());
//                        sb.append(",");
//                    }
//                    car.setIsWarning(DictConstants.IS_WARNING.NO.getKey());
                }
                if(StringUtils.isNotBlank(sb)) {
                    String token = getOpenToken();
                    Map<String, String> map = new HashMap<String, String>(3);
                    map.put("token", token);
                    map.put("cid", CLIENTID);
                    map.put("srt", SRT);
                    map.put("userflag", "sth");
                    map.put("vnos", sb.toString());
                    String result = send(URL + "/save/apis/vnoOutDel", map);
                    if(StringUtils.isNotBlank(result) && "1".equals(result)) {
                        // 更新订阅状态
                        vehicleService.updateBatchById(cars);
                        return true;
                    }
                }
            } catch (Exception e) {
                System.out.println("e:" + e.getMessage());
            }
        }
        return false;
    }

    /**
     * 请求
     * @param url
     * @param map
     * @return
     * @throws Exception
     */
    private String send(String url, Map<String, String> map) throws Exception {
        DataExchangeService des = new DataExchangeService(50000, 80000);
        // 通过 https 方式调用，此方法内部会使用私钥生成签名参数 sign,私钥不会发送
        String res = des.postHttps(url, map);
        if (StringUtils.isNotBlank(res)) {
            JSONObject jsonObject = JSON.parseObject(res);
            // status == 1001代表成功
            if(jsonObject.get("status") != null) {
                String status = jsonObject.getString("status");
                if("1001".equals(status)) {
                    return jsonObject.getString("result");
                } else if("1003".equals(status) || "1004".equals(status)) {
                    throw new ServiceException("服务调用次数已达上限");
                } else if("1012".equals(status)) {
                    throw new ServiceException("账号已禁用");
                } else if("1013".equals(status)) {
                    throw new ServiceException("账号已过期");
                } else if("1017".equals(status)) {
                    throw new ServiceException("账号欠费");
                }
            }
        }
        return null;
    }

}
